<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 当前激活的副作用函数
    var activeEffect
    // 存放副作用函数的桶
    var bucket = new Map() // [a:Set([fn,fn,fn,....]),b:Set([fn,fn,fn,fn....])]
   
    // 收集依赖
    function effect(fn) {
      activeEffect = fn
      fn()
      activeEffect = null
    }

    function reactive(data) {
      if(!(typeof data === 'object' && data!==null)) return
      return new Proxy(data, {
        get(target, key) {
          if (activeEffect) {
            let depSet = bucket.get(key)
            if (!depSet) {
              depSet = new Set()
              bucket.set(key, depSet)
            }
            depSet.add(activeEffect)
          }
          return target[key]
        },
        set(target, key, value) {
          target[key] = value
          let depSet = bucket.get(key)
          depSet.forEach(fn => fn())
          return true
        }
      })
    }

    var obj = {
      a: 1,
      b: 2
    }
    const proxy = reactive(obj)

    function effect1() {
      document.body.innerHTML = proxy.a
    }

    function effect2() {
      console.log(proxy.b);
    }

    effect(effect1)
    effect(effect2)

    effect(() => {
      console.log(proxy.a);
    })






    setTimeout(() => {
      proxy.a = 22
    }, 2000);
  </script>
</body>

</html>